package com.xusheng.cli.controller.proxy;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xusheng.cli.common.annotation.OperationLogAnno;
import com.xusheng.cli.common.base.ProxyInfoForSession;
import com.xusheng.cli.common.base.Result;
import com.xusheng.cli.common.constant.Constant;
import com.xusheng.cli.common.enums.OperationType;
import com.xusheng.cli.entity.backAgentModule.BackAgent;
import com.xusheng.cli.entity.userModule.LoginInfoVO;
import com.xusheng.cli.service.BackAgentService;
import com.xusheng.cli.service.ProxyPermissionService;
import com.xusheng.cli.service.RoleService;
import com.xusheng.cli.service.UserService;
import com.xusheng.cli.tools.StpProxyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


/**
 * 登录相关
 *
 * @author jy
 * @since 2020-04-11 14:57
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/proxy/v1/login")
public class LoginController {

    @Resource
    private BackAgentService backAgentService;

    @Resource
    private RoleService roleService;

    @Resource
    private ProxyPermissionService proxyPermissionService;

    @Resource
    private UserService userService;

    @PostMapping("/login")
    @OperationLogAnno(module = "登录模块", type = OperationType.LOGIN, desc = "登录")
    public Result<Object> login(@Validated @RequestBody LoginInfoVO loginInfoVO) {
        SaSession tokenSession = StpUtil.getTokenSession();
        Object attribute = tokenSession.get(Constant.CAPTCHA_SESSION_KEY);
        if (attribute == null) {
            return Result.error("验证码已失效,请刷新页面后重试!");
        }
        if (!StrUtil.equalsIgnoreCase((CharSequence) attribute, loginInfoVO.getVerificationCode())) {
            return Result.error("验证码不正确!");
        }
        tokenSession.delete(Constant.CAPTCHA_SESSION_KEY);
        LambdaQueryWrapper<BackAgent> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(BackAgent::getAccount, loginInfoVO.getAccount()).eq(BackAgent::getState, 1);
        BackAgent user = backAgentService.getOne(wrapper);
        if (user == null) {
            return Result.error("账户或密码错误");
        }
        String password = user.getPassword();
        Assert.notBlank(password, "密码不能为空");
        boolean b = DigestUtil.bcryptCheck(loginInfoVO.getPassword(), password);
        if (b) {
        /*    String ipWhitelist = backAgentService.getIpWhitelist(user.getId());
            if (StrUtil.isNotBlank(ipWhitelist)) {
                String clientIp = IpUtil.getClientIp();
                log.info("总后台登录,ip:{}", clientIp);
                Assert.isTrue(ipWhitelist.contains(clientIp), "当前设备ip:{},无法登录", clientIp);
            }*/
            Long userId = user.getId();
            StpProxyUtil.login(userId);
            StpProxyUtil.getSession().set(Constant.PROXY, new ProxyInfoForSession(userId, user.getAccount(), user.getName(), user.getLevel()));
            return Result.success(StpProxyUtil.getTokenValue());
        }
        return Result.error("账号或密码错误");
    }

    /**
     * 获取当前登录人的角色
     *
     * @author jy
     * @since 2022/1/18 10:45
     */
    @GetMapping("/roles")
    public Result<List<String>> getRoles() {
        return Result.success(roleService.getRolesByUserId());
    }

    /**
     * 获取当前登录人的页面权限
     *
     * @author jy
     * @since 2022/1/18 10:45
     */
    @GetMapping("/permission")
    public Result<List<String>> getPermissions() {
        return Result.success(proxyPermissionService.getAllPermissionUrlByUserId());
    }

    /**
     * 获取当前登录人的按钮权限
     *
     * @author jy
     * @since 2022/1/18 10:46
     */
    @GetMapping("/btnPermission")
    public Result<List<String>> getBtnPermission() {
        return Result.success(proxyPermissionService.getAllBtnPermissionByUserId());
    }

    /**
     * 登出
     *
     * @author jy
     * @since 2022/1/18 16:15
     */
    @GetMapping("/signOut")
    public Result<Object> signOut() {
        StpProxyUtil.logout();
        return Result.success();
    }

    /**
     * 获取修改当前登录人密码的验证码
     *
     * @author jy
     * @since 2022/1/18 10:47
     */
    @GetMapping("verificationCode")
    public void verification(HttpServletResponse response) {
        userService.getVerification(response);
    }

}
